# coding=utf8
from ctypes import (c_int8, c_int16, c_int32, c_int64,
                    c_float, c_double, c_uint16, c_uint32, c_uint64,
                    cast, pointer, POINTER)


def __j_primitive(c_type):
    def j(val):
        return c_type(val).value

    return j


j_byte = __j_primitive(c_int8)
j_short = __j_primitive(c_int16)
j_int = __j_primitive(c_int32)
j_long = __j_primitive(c_int64)
j_char = __j_primitive(c_uint16)
j_float = __j_primitive(c_float)
j_double = __j_primitive(c_double)
j_u_int = __j_primitive(c_uint32)
j_u_long = __j_primitive(c_uint64)
# MAX_INTEGER = 0x7fffffff
# MIN_INTEGER = 0x80000000

j_c_type = {
    id(j_byte): c_int8,
    id(j_short): c_int16,
    id(j_int): c_int32,
    id(j_long): c_int64,
    id(j_char): c_uint16,
    id(j_float): c_float,
    id(j_double): c_double,
    id(j_u_int): c_uint32,
    id(j_u_long): c_uint64
}


def j_cast(j_type, j_cast_type):
    c_type = j_c_type[id(j_type)]
    c_cast_type = j_c_type[id(j_cast_type)]

    def cast_to(val):
        c_val = c_type(val)
        p = pointer(c_val)
        ret = cast(p, POINTER(c_cast_type))
        return ret.contents.value

    return cast_to


d2i = j_cast(j_double, j_int)
d2l = j_cast(j_double, j_long)

__all__ = ['j_byte', 'j_short', 'j_int', 'j_long',
           'j_char',
           'j_float', 'j_double',
           'j_u_int', 'j_u_long',
           'd2i', 'd2l']
